<?php

namespace Hilaoyu\LaravelExtend;


use Hilaoyu\Utils\UtilArr;
use Hilaoyu\Utils\UtilStr;
use Illuminate\Http\Request;


abstract class ControllerBaseResource extends ControllerBase
{
    public function __construct()
    {

        parent::__construct();

    }

    /**
     * @return Entity
     */
    abstract protected function entity();


    public function getModels(Request $request)
    {
        $withPager = intval($request->route('_with_pager'));
        if ($withPager > 0) {
            $pager = $this->getPager($withPager);
        } else {
            $pager = [
                'offset' => 0,
                'start' => 0,
                'page' => 0,
                'total' => null,
            ];
        }

        $entity = $this->entity();

        $models = $entity->select(function ($query) use ($request) {
            return $this->alterModelsQuery($query, $request);
        }, $this->alterModelsSort($request), $pager['offset'], $pager['start'], $pager['total']);


        if ($withPager > 0) {
            comResponse()->withPager($pager);
        }

        $models = $this->alterModelsLoaded($models, $request);
        comResponse()->with($models, 'models');

        comResponse()->success();


        return $this->alterModelsResponse($models,$request) ?? $this->renderingResponse();
    }


    public function getModel(Request $request)
    {
        $id = $this->alterModelGetId($request);
        $id = value($id);

        $entity = $this->entity();

        $model = null;
        if (!empty($id)) {
            $model = $entity->findById($id);
            if (empty($model)) {
                if (!config('app.debug')) {
                    abort(404, '资源没找到');
                }

                comResponse()->failed('资源没找到', 404);
            }
        }
        if (!$model) {
            $model = $entity->model();
        }

        $model = $this->alterModelLoaded($model, $request);


        comResponse()->with($model, 'model')
            ->success();


        return $this->alterModelResponse($model,$request) ?? $this->renderingResponse();
    }


    public function modelSave(Request $request)
    {
        $model = null;
        try{
            $id = $this->alterModelSaveId($request);
            $id = value($id);

            $data = $this->alterModelSaveData($request, $id);

            if(empty($data)){
                throw new \Exception('数据错误');
            }
            //dd($data);
            $entity = $this->entity();

            $model = $entity->save($data, $id);
            //dd($model,$entity->getError());
            if (!$model) {
                $errors = $entity->getError();
                if(!config("app.debug")){
                    foreach ($errors as $ek => $ev){
                        if (UtilStr::contains(UtilArr::toString($ev),'SQLSTATE', false)){
                            unset($errors[$ek]);
                        }
                    }
                }

                comResponse()
                    ->withErrors($errors);
                throw new \Exception('保存失败');
            }

            $model = $this->alterModelLoaded($model, $request);

            comResponse()->success('保存成功');
        }catch (\Exception $exception){
            comResponse()
                ->failed($exception->getMessage());
        }



        return $this->alterModelSaveRedirect($model, $request);

    }

    public function modelDeleteMulti(Request $request)
    {
        $id =  $this->alterModelDeleteId($request);
        $force = '1' == $request->input('force','');
        $id = (array)$id;
        if (empty($id)) {
            comResponse()->failed('参数错误');
            return $this->alterModelDeleteRedirect($request);
        }
        $entity = $this->entity();

        if ($entity->deleteMulti(function ($query) use ($id) {
            return $query->whereIn('id', $id);
        },$force)
        ) {
            comResponse()->success('删除成功');
        } else {
            comResponse()->failed('删除失败')->withErrors($entity->getError());
        }
        return $this->alterModelDeleteRedirect($request);
    }


    public function modelDelete(Request $request)
    {
        return $this->modelDeleteMulti($request);
    }


    protected function alterModelsQuery($query, Request $request)
    {
        return $query;
    }

    protected function alterModelsSort(Request $request): array
    {
        return $request->route('_with_sort', []);
    }

    protected function alterModelsLoaded($models, Request $request)
    {
        return $models;
    }

    protected function alterModelsResponse($models,Request $request)
    {

    }


    /**
     * @param $model \Illuminate\Database\Eloquent\Model
     * @param Request $request
     * @return \Illuminate\Database\Eloquent\Model
     */
    protected function alterModelLoaded($model, Request $request)
    {
        return $model;
    }

    protected function alterModelResponse($model,Request $request)
    {

    }


    protected function alterModelSaveId(Request $request)
    {
        return $request->route('id');
    }

    protected function alterModelGetId(Request $request)
    {
        return $request->route('id');
    }

    protected function alterModelDeleteId(Request $request)
    {
        return $request->route('id',$request->input('id',[]));
    }


    protected function alterModelSaveData(Request $request, $id = '')
    {
        return [];
    }

    protected function alterModelSaveRedirect($model, Request $request)
    {
        if($request->ajax() || '_json_' == $request->route('_view','')) {
            return comResponse()->with($model)->json();

        }
        return comResponse()->with($model, 'model')->back();
    }

    protected function alterModelDeleteRedirect(Request $request)
    {
        return ($request->ajax() || '_json_' == $request->route('_view','')) ? comResponse()->json() : comResponse()->back();
    }


}
